<script setup lang="ts">
  import GoodSelectModal from './good-select-modal/index.vue'
  import { ref } from 'vue'
  import { Good } from '../types'
  import { ElIcon, UploadFile } from 'element-plus'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import infoTip from '@/config/info-tip'
  import _ from 'lodash'
  import { useGetInfoByProductOrPartCode } from '@/services/pages/code/useCode'
  import { UploadFilled } from '@element-plus/icons-vue'
  import VideoPreview from '../custom-info/VideoPreview.vue'
  import videoPreviewImg from '@/assets/image/pages/order/new/video.png'

  const { codeInfo, getInfoLoading, getInfo } = useGetInfoByProductOrPartCode()

  defineOptions({
    name: 'GoodsReturnFactoryCreate',
  })

  const props = defineProps({
    userId: {
      type: String,
      default: () => '',
    },
  })

  const addCommodityDrawerVisible = ref(false)
  const goods = ref<Array<Good>>([
    {
      snCode: '',
      goodType: '',
      goodBrand: '',
      goodCode: '',
      goodName: '',
      goodSpec: '',
      qty: 0,
      warrantyStart: '',
      goodId: '',
      goodSpecId: '',
      warrantyEnd: '',
      returnFactoryDesc: '',
      returnFactoryPictureList: [],
      isFixed: true,
      type: 1,
      repairVideoList: [],
    },
  ])
  const searchSnCodeVal = ref('')
  const pictureColumnWidth = ref(130)
  const videoColumnWidth = ref(130)
  const videoPreviewModalVisible = ref(false)
  const videoPreviewUrlList = ref<Array<string>>([])
  const currentPreviewVideoIndex = ref(-1)

  const getRowClassName = (data: { row: Good; rowIndex: number }) => {
    if (data.rowIndex === 0) {
      return 'fixed-row'
    }
  }

  const handleUploadPicture = (file: UploadFile, index: number) => {
    if (file.raw) {
      if (!file.raw.type.includes('image')) {
        HMessageBox.error('只能上传图片')
        return
      }

      if (goods.value[index].returnFactoryPictureList.length >= 8) {
        HMessageBox.error('最多上传8张图片')
        return
      }

      if (file.raw.size / 1024 / 1024 > 50) {
        HMessageBox.error('最大只能上传50MB的图片')
        return
      }

      goods.value[index].returnFactoryPictureList.push({
        file,
        url: URL.createObjectURL(file.raw),
      })

      setPictureColumnWidth()
    }
  }

  const handleUploadVideo = (file: UploadFile, index: number) => {
    if (file.raw) {
      if (!file.raw.type.includes('video')) {
        HMessageBox.error('只能上传视频')
        return
      }

      if (goods.value[index].repairVideoList.length >= 8) {
        HMessageBox.error('最多上传8个视频')
        return
      }

      if (file.raw.size / 1024 / 1024 > 50) {
        HMessageBox.error('最大只能上传50MB的视频')
        return
      }

      goods.value[index].repairVideoList.push({
        file,
        url: URL.createObjectURL(file.raw),
      })

      setVideoColumnWidth()
    }
  }

  const handleRemovePicture = (rowIndex: number, pictureIndex: number) => {
    goods.value[rowIndex].returnFactoryPictureList.splice(pictureIndex, 1)
    setPictureColumnWidth()
  }

  const handleRemoveVideo = (rowIndex: number, videoIndex: number) => {
    goods.value[rowIndex].repairVideoList.splice(videoIndex, 1)
    setVideoColumnWidth()
  }

  const setPictureColumnWidth = () => {
    let maxPictureLength = Math.max(
      ...goods.value.map((item) => item.returnFactoryPictureList.length),
    )

    // 在图片数量小于8张时要把上传按钮的宽度计算进去
    if (maxPictureLength < 8) {
      maxPictureLength += 1
    }

    // 这是为了解决删剩一张图时，列宽会变得很小，导致标题会换行
    if (maxPictureLength > 0) {
      pictureColumnWidth.value = maxPictureLength * 60 + (maxPictureLength - 1) * 8 + 24
    }

    if (pictureColumnWidth.value < 130) {
      pictureColumnWidth.value = 130
    }
  }

  const setVideoColumnWidth = () => {
    let maxVideoLength = Math.max(...goods.value.map((item) => item.repairVideoList.length))

    // 在视频数量小于8个时要把上传按钮的宽度计算进去
    if (maxVideoLength < 8) {
      maxVideoLength += 1
    }

    // 这是为了解决删剩一个图片时，列宽会变得很小，导致标题会换行
    if (maxVideoLength > 0) {
      videoColumnWidth.value = maxVideoLength * 60 + (maxVideoLength - 1) * 8 + 24
    }

    if (videoColumnWidth.value < 130) {
      videoColumnWidth.value = 130
    }
  }

  const onSearchAndAddGood = async () => {
    if (!searchSnCodeVal.value) {
      return
    }

    await getInfo(searchSnCodeVal.value)
    if (!codeInfo.value) {
      HMessageBox.warning(infoTip.returnFactory.create.code_search_result_empty)
      return
    }

    const isCodeExist = goods.value.some(
      (good) =>
        good.goodId === codeInfo.value.goodsId &&
        good.goodSpecId === codeInfo.value.goodsSpecId &&
        good.snCode === codeInfo.value.code,
    )
    if (isCodeExist) {
      HMessageBox.error(infoTip.returnFactory.create.code_is_exist)
      return
    }

    goods.value.push({
      snCode: codeInfo.value.code,
      goodType: codeInfo.value.type === 1 ? '成品' : '物料',
      goodBrand: codeInfo.value.goodsBrand,
      goodCode: codeInfo.value.goodsCode,
      goodName: codeInfo.value.goodsName,
      goodSpec: codeInfo.value.goodsSpecName,
      qty: 1,
      type: codeInfo.value.type,
      warrantyStart: codeInfo.value.warrantyStartTime || '',
      goodId: codeInfo.value.goodsId,
      goodSpecId: codeInfo.value.goodsSpecId,
      warrantyEnd: codeInfo.value.warrantyEndTime || '',
      returnFactoryDesc: '',
      returnFactoryPictureList: [],
      isFixed: false,
      repairVideoList: [],
    })

    searchSnCodeVal.value = ''
    HMessage.success('添加成功')
  }

  const handleVideoPreview = (goodIndex: number, videoIndex: number) => {
    videoPreviewModalVisible.value = true
    currentPreviewVideoIndex.value = videoIndex
    videoPreviewUrlList.value = goods.value[goodIndex].repairVideoList.map((item) => item.url)
  }

  const handleGoodSelectModalUpdate = (data: Array<Good>) => {
    const _goods: Array<Good> = []
    const goodIds = new Set(goods.value.map((good) => good.goodId))
    const goodSpecIds = new Set(goods.value.map((good) => good.goodSpecId))
    const snCodes = new Set(goods.value.filter((good) => !!good.snCode).map((good) => good.snCode))

    // 创建查找映射，提高查找效率
    const goodsMap = new Map()
    goods.value.forEach((good) => {
      const key = `${good.goodId}-${good.goodSpecId}`
      if (good.snCode) {
        const snKey = `${key}-${good.snCode}`
        goodsMap.set(snKey, good)
      } else {
        goodsMap.set(key, good)
      }
    })

    data.forEach((item) => {
      const isOldGood = goodIds.has(item.goodId) && goodSpecIds.has(item.goodSpecId)

      if (!item.snCode) {
        // 处理没有序列号的商品
        if (isOldGood) {
          const key = `${item.goodId}-${item.goodSpecId}`
          const existingGood = goodsMap.get(key)
          if (existingGood) {
            _goods.push(existingGood)
          }
        } else {
          _goods.push(item)
        }
      } else {
        // 处理有序列号的商品
        const isOldSnCode = isOldGood && snCodes.has(item.snCode)
        if (isOldSnCode) {
          const snKey = `${item.goodId}-${item.goodSpecId}-${item.snCode}`
          const existingGood = goodsMap.get(snKey)
          if (existingGood) {
            _goods.push(existingGood)
          }
        } else {
          _goods.push(item)
        }
      }
    })

    goods.value = _goods

    if (goods.value.every((item) => !item.isFixed)) {
      goods.value.unshift(createDefaultRepairGood())
    }
  }

  function createDefaultRepairGood(): Good {
    return {
      snCode: '',
      goodType: '',
      goodBrand: '',
      goodCode: '',
      goodName: '',
      goodSpec: '',
      qty: 0,
      warrantyStart: '',
      goodId: '',
      goodSpecId: '',
      warrantyEnd: '',
      returnFactoryDesc: '',
      returnFactoryPictureList: [],
      isFixed: true,
      type: 1,
      repairVideoList: [],
    }
  }

  defineExpose({
    getList: () => {
      // 删除出调用固定行数据
      return _.cloneDeep(goods.value).filter((good) => !good.isFixed)
    },
  })
</script>

<template>
  <div class="new-return-factory-commodity-list">
    <div class="title">产品详情</div>
    <div class="table-wrapper">
      <div class="table">
        <el-table
          :border="true"
          :data="goods"
          stripe
          max-height="350"
          :row-class-name="getRowClassName"
          scrollbar-always-on
        >
          <!-- 序号 -->
          <el-table-column width="50" fixed="left" :align="'center'" type="index" label="序号" />

          <!-- 条码 -->
          <el-table-column width="300" prop="snCode" label="条码" fixed="left">
            <template #default="{ row }">
              <template v-if="row.isFixed">
                <div class="sncode-search">
                  <el-input v-model.trim="searchSnCodeVal" placeholder="请输入条码" clearable />
                  <h-button type="primary" :loading="getInfoLoading" @click="onSearchAndAddGood">
                    搜索并添加
                  </h-button>
                </div>
              </template>
              <template v-else>{{ row.snCode }}</template>
            </template>
          </el-table-column>

          <!-- 产品类型 -->
          <el-table-column prop="goodType" show-overflow-tooltip label="产品类型" width="140" />

          <!-- 品牌 -->
          <el-table-column prop="goodBrand" show-overflow-tooltip label="品牌" width="140" />

          <!-- 产品编号 -->
          <el-table-column prop="goodCode" show-overflow-tooltip label="产品编号" width="140" />

          <!-- 产品名称 -->
          <el-table-column prop="goodName" show-overflow-tooltip label="产品名称" width="160" />

          <!-- 规格 -->
          <el-table-column prop="goodSpec" show-overflow-tooltip label="规格" width="160" />

          <!-- 数量 -->
          <el-table-column label="数量" width="140">
            <template #default="{ row }">
              <el-input v-if="!row.isFixed" v-model.trim="row.qty" placeholder="请输入数量" />
              <template v-else>{{ row.qty >= 1 ? row.qty : '' }}</template>
            </template>
          </el-table-column>

          <!-- 质保开始 -->
          <el-table-column prop="warrantyStart" label="质保开始" width="140" />

          <!-- 质保结束 -->
          <el-table-column prop="warrantyEnd" label="质保结束" width="140" />

          <!-- 返厂产品问题 -->
          <el-table-column prop="returnFactoryDesc" label="返厂产品问题" width="280">
            <template #default="{ row }">
              <el-input
                v-if="!row.isFixed"
                v-model.trim="row.returnFactoryDesc"
                resize="both"
                type="textarea"
                maxlength="200"
                show-word-limit
                placeholder="请输入返厂产品问题"
                class="return-factory-desc"
              />
            </template>
          </el-table-column>

          <!-- 返厂图片 -->
          <el-table-column
            prop="returnFactoryPictureList"
            label="返厂图片"
            :width="pictureColumnWidth"
          >
            <template #default="{ row, $index }">
              <div v-if="!row.isFixed" class="picture-wrapper">
                <template v-for="(img, index) in row.returnFactoryPictureList" :key="index">
                  <h-image
                    :preview-src-list="(row.returnFactoryPictureList as Good['returnFactoryPictureList']).map((item) => item.url)"
                    :width="60"
                    :height="37.5"
                    fit="scale-down"
                    :src="img.url"
                    :initial-index="index"
                    :padding="2"
                    :mask-btn-gap="3"
                    :show-del-btn="!img.id"
                    @del="handleRemovePicture($index, index)"
                  />
                </template>
                <el-upload
                  v-if="row.returnFactoryPictureList.length < 8"
                  action="#"
                  multiple
                  accept="image/*"
                  :auto-upload="false"
                  :show-file-list="false"
                  drag
                  :on-change="(file: UploadFile) => handleUploadPicture(file, $index)"
                >
                  <el-icon :size="24" color="#007cff">
                    <UploadFilled />
                  </el-icon>
                </el-upload>
              </div>
            </template>
          </el-table-column>

          <!-- 返厂视频 -->
          <el-table-column prop="repairVideoList" label="返厂视频" :width="pictureColumnWidth">
            <template #default="{ row, $index }">
              <div v-if="!row.isFixed" class="picture-wrapper">
                <template v-for="(img, index) in row.repairVideoList" :key="index">
                  <h-image
                    :width="60"
                    :height="37.5"
                    fit="scale-down"
                    :src="videoPreviewImg"
                    :initial-index="index"
                    :padding="2"
                    :mask-btn-gap="3"
                    :show-del-btn="!img.id"
                    :is-show-img-preview="false"
                    @del="handleRemoveVideo($index, index)"
                    @preview="handleVideoPreview($index, index)"
                  />
                </template>
                <el-upload
                  v-if="row.repairVideoList.length < 8"
                  action="#"
                  multiple
                  accept="video/*"
                  :auto-upload="false"
                  :show-file-list="false"
                  :on-change="(file: UploadFile) => handleUploadVideo(file, $index)"
                  drag
                >
                  <el-icon :size="24" color="#007cff">
                    <UploadFilled />
                  </el-icon>
                </el-upload>
              </div>
            </template>
          </el-table-column>

          <!-- 操作 -->
          <el-table-column width="100" fixed="right" label="操作">
            <template #default="{ row, $index }">
              <h-link v-if="row.isFixed" @click="addCommodityDrawerVisible = true">选择产品</h-link>
              <h-link v-else type="error" @click="goods.splice($index, 1)">删除</h-link>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <good-select-modal
      v-model="addCommodityDrawerVisible"
      :user-id="props.userId"
      :selected-list="_.cloneDeep(goods)"
      @update="handleGoodSelectModalUpdate"
    />

    <video-preview
      v-model="videoPreviewModalVisible"
      :initial-index="currentPreviewVideoIndex"
      :video-list="videoPreviewUrlList"
    />
  </div>
</template>

<style scoped lang="scss">
  .picture-wrapper {
    display: flex;
    gap: 8px;
    height: 40px;

    :deep(.el-upload) {
      width: 60px;
      height: 37.5px;

      .el-upload-dragger {
        padding: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }
    }
  }

  .sncode-search {
    display: flex;
    column-gap: 5px;
  }

  :deep(.el-table__body-wrapper) {
    .el-scrollbar {
      .el-scrollbar__wrap {
        box-sizing: border-box;
        padding-bottom: 13px;
      }
    }
  }

  .return-factory-desc {
    :deep(.el-textarea__inner) {
      height: 28px;
      min-height: 28px !important;
      max-height: 220px !important;
      width: 250px !important;
    }
  }

  :deep(.fixed-row) {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
    z-index: 3;
  }

  .new-return-factory-commodity-list {
    display: flex;
    flex-direction: column;
    row-gap: 8px;
    height: 100%;

    .title {
      font-size: 14px;
      font-weight: bold;
      padding-left: 6px;
      border-left: 3px solid $primaryColor;
    }

    .table-wrapper {
      flex: 1;
    }
  }
</style>
